home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / Amiga-E / E_v3.2a / Src / Lang / Elex.e next >
Text File  |  1992-09-02  |  5KB  |  194 lines

  1. -> Tiny E Lexical Analyzer. Of little use sofar, but nice example
  2.  
  3. OPT REG=5
  4.  
  5. MODULE 'tools/ctype', 'tools/file', 'class/hash'
  6.  
  7. DEF src_begin=NIL, src_size, src_end, p:PTR TO CHAR, curline=1, x=" ",y,
  8.     keyhash:PTR TO hashtable,keylist:PTR TO LONG
  9.  
  10. ENUM NONE,ER_GARBAGE,ER_STRING,ER_COMMENT
  11.  
  12. OBJECT keylink OF hashlink
  13.   token:INT
  14. ENDOBJECT
  15.  
  16. PROC main() HANDLE
  17.   WriteF('Tiny E Lexical Analyzer (c) 1994 Wouter\n')
  18.   src_begin,src_size:=readfile(arg)
  19.   src_end:=(p:=src_begin)+src_size
  20.   lex_keys()
  21.   WHILE x<>256
  22.     IF x<256
  23.       WriteF('\c ',x)
  24.     ELSEIF x>512
  25.       WriteF('\s ',{x}+2)
  26.     ELSEIF x>=300
  27.       WriteF('{\s} ',keylist[x-300])
  28.     ELSEIF x=260
  29.       WriteF('"\s" ',y)
  30.     ELSE
  31.       WriteF('\d ',x-256)
  32.     ENDIF
  33.     x,y:=lex()
  34.   ENDWHILE
  35.   WriteF('\n')
  36. EXCEPT DO
  37.   IF src_begin THEN freefile(src_begin)
  38.   SELECT exception
  39.     CASE NONE;   WriteF('no errors.\n')
  40.     CASE "OPEN"; WriteF('no file!\n')
  41.     CASE "MEM";  WriteF('no mem!\n')
  42.     DEFAULT;     printerr(exception)
  43.   ENDSELECT
  44. ENDPROC
  45.  
  46. PROC printerr(n)
  47.   DEF ers[200]:STRING,pos,a,b,e
  48.   b:=e:=p
  49.   WHILE b[]--<>"\n" DO NOP
  50.   b++
  51.   WHILE e[]<>"\n" DO e++
  52.   StrCopy(ers,b,e-b)
  53.   pos:=p-b-1
  54.   WriteF('\nERROR: \s\nLINE: \d\n\s\n',
  55.     ListItem([
  56.       '',
  57.       'garbage in line',
  58.       'unmatched \a or \q',
  59.       'unmatched */',
  60.       '',
  61.       '',
  62.       ''
  63.     ],n),curline,ers)
  64.   IF pos>0 THEN FOR a:=1 TO pos DO WriteF(' ')
  65.   WriteF('^\n')
  66. ENDPROC
  67.  
  68. /*----------------------------LEX-----------------------------------*/
  69.  
  70. ENUM LEX_EOF=256,
  71.      LEX_EOL,
  72.      LEX_INTEGER,
  73.      LEX_FLOAT,
  74.      LEX_IDENT,
  75.      LEX_STRINGA,
  76.      LEX_STRINGQ
  77.  
  78.  
  79. ->   ; , := + - * / = > < >= <= <> ( ) : { } [ ] ^ . ` ! | ++ -- <=> :: /* */ ->
  80.  
  81.  
  82. PROC lex()
  83.   DEF a,b,c,d,l:PTR TO keylink
  84.   LOOP
  85.     SELECT 256 OF c:=p[]++
  86.       CASE ",","*","=","(",")","{","}","[","]","^",".","`","!","|"
  87.         RETURN c
  88.       CASE "+"
  89.         RETURN IF p[]="+" THEN p++ BUT "++" ELSE "+"
  90.       CASE "-"
  91.         IF (c:=p[])=">"
  92.           WHILE p[]++<>"\n"
  93.           ENDWHILE
  94.           curline++
  95.         ELSEIF c="-"
  96.           p++
  97.           RETURN "--"
  98.         ELSE
  99.           RETURN "-"
  100.         ENDIF
  101.       CASE "/"
  102.         IF p[]<>"*" THEN RETURN "/"
  103.         p++
  104.         a:=1
  105.         b:=p; d:=curline
  106.         REPEAT
  107.           IF (c:=b[]++)="/"
  108.             IF b[]="*" THEN b++ BUT a++
  109.           ELSEIF c="*"
  110.             IF b[]="/" THEN b++ BUT a--
  111.           ELSEIF c="\n"
  112.            IF b>src_end THEN Raise(ER_COMMENT)
  113.            d++
  114.           ENDIF
  115.         UNTIL a=0
  116.         p:=b
  117.         curline:=d
  118.       CASE ">"
  119.         RETURN IF p[]="=" THEN p++ BUT ">=" ELSE ">"
  120.       CASE "<"
  121.         IF (c:=p[])="="
  122.           p++
  123.           RETURN IF p[]=">" THEN p++ BUT "<=>" ELSE "<="
  124.         ELSEIF c=">"
  125.           p++
  126.           RETURN "<>"
  127.         ELSE
  128.           RETURN "<"
  129.         ENDIF
  130.       CASE ":"
  131.         RETURN IF (c:=p[])=":" THEN p++ BUT "::" ELSE IF c="=" THEN p++ BUT ":=" ELSE ":"
  132.       CASE ";","\n"
  133.         IF p>src_end THEN RETURN (p:=src_end) BUT LEX_EOF
  134.         curline++
  135.         WriteF('\n[\d] ',curline)
  136.         RETURN LEX_EOL        -> conditional
  137.       CASE " ", "\t"
  138.         /* whitespace, do nothing */
  139.       CASE "0" TO "9", "$", "%"
  140.         a,b:=Val(p-1)
  141.         IF b=0 THEN RETURN c
  142.         p:=p+b-1
  143.         RETURN LEX_INTEGER, a
  144.       CASE "a" TO "z", "A" TO "Z", "_"
  145.         a:=p-1; c:=p[]
  146.         WHILE isalnum(c) OR (c="_") DO p++ BUT c:=p[]
  147.         IF l:=keyhash.find(a,p-a) THEN RETURN l.token
  148.         NEW b[c:=p-a+1]
  149.         AstrCopy(b,a,c)
  150.         RETURN LEX_IDENT,b
  151.       CASE "\q", "\a"
  152.         a:=p
  153.         WHILE (a[]<>c) AND (a[]<>"\n") DO a++
  154.         IF a[]="\n" THEN Raise(ER_STRING)
  155.         b:=p
  156.         p:=a+1
  157.         RETURN IF c="\a" THEN LEX_STRINGQ ELSE LEX_STRINGA, b
  158.       DEFAULT
  159.         Raise(ER_GARBAGE)
  160.     ENDSELECT
  161.   ENDLOOP
  162. ENDPROC
  163.  
  164. ENUM K_PROC=300,K_ENDPROC,K_IF,K_ENDIF,K_VOID,K_WHILE,K_ENDWHILE,K_FOR,
  165.      K_ENDFOR,K_SELECT,K_CASE,K_DEFAULT,K_ENDSELECT,K_REPEAT,K_UNTIL,
  166.      K_JUMP,K_DEF,K_ELSE,K_INCBIN,K_LONG,K_INT,K_CHAR,K_INC,K_DEC,K_THEN,
  167.      K_LOOP,K_ENDLOOP,K_DO,K_AND,K_OR,K_CONST,K_OPT,K_MODULE,K_STACK,
  168.      K_EXIT,K_LARGE,K_ASM,K_NOWARN,K_TO,K_STEP,K_ARRAY,K_STRING,K_DIR,
  169.      K_PTR,K_OF,K_ELSEIF,K_LIST,K_OBJECT,K_ENDOBJECT,K_SIZEOF,K_RETURN,
  170.      K_OSVERSION,K_ENUM,K_SET,K_BUT,K_HANDLE,K_EXCEPT,K_RAISE,K_EXPORT,
  171.      K_REG,K_END,K_IS,K_NEW,K_PUBLIC,K_PRIVATE,K_SUPER
  172.  
  173. PROC lex_keys()
  174.   DEF a,b,h,kl:PTR TO keylink,dat,datl
  175.   NEW keyhash.hashtable(HASH_NORMAL)
  176.   keylist:=[
  177.     'PROC','ENDPROC','IF','ENDIF','VOID','WHILE','ENDWHILE','FOR',
  178.     'ENDFOR','SELECT','CASE','DEFAULT','ENDSELECT','REPEAT','UNTIL',
  179.     'JUMP','DEF','ELSE','INCBIN','LONG','INT','CHAR','INC','DEC','THEN',
  180.     'LOOP','ENDLOOP','DO','AND','OR','CONST','OPT','MODULE','STACK',
  181.     'EXIT','LARGE','ASM','NOWARN','TO','STEP','ARRAY','STRING','DIR',
  182.     'PTR','OF','ELSEIF','LIST','OBJECT','ENDOBJECT','SIZEOF','RETURN',
  183.     'OSVERSION','ENUM','SET','BUT','HANDLE','EXCEPT','RAISE','EXPORT',
  184.     'REG','END','IS','NEW','PUBLIC','PRIVATE','SUPER'
  185.   ]
  186.   FOR a:=0 TO ListLen(keylist)-1
  187.     datl:=StrLen(dat:=keylist[a])
  188.     b,h:=keyhash.find(dat,datl)
  189.     NEW kl
  190.     kl.token:=a+K_PROC
  191.     keyhash.add(kl,h,dat,datl)
  192.   ENDFOR
  193. ENDPROC
  194.